"""
Mock gRPC 仿真服务器
用于本地测试 gRPC Agent Adapter，无需真实仿真系统

作者: AI Assistant
版本: 1.0
基于项目现有代码构建
"""
import sys
import os
import grpc
import json
import math
import time
import numpy as np
import argparse
from concurrent import futures
from typing import List, Dict, Optional, Tuple
from dataclasses import dataclass

# 添加项目路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/../")

os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "python"
# 仿真系统通信协议
from sh15.simulation import simserver_pb2
from sh15.simulation import simserver_pb2_grpc

# 核心环境和单位
from sh15.core.CoreEnvironment import CoreEnvironment
from sh15.core.config import GameConfig
from sh15.core.units import WhiteBoat, WhiteDrone, BlackBoat
from sh15.core.LockingSystem import LockingSystem
from sh15.core.DroneManager import DroneManager

# 智能体和动作执行
from sh15.agents.base_agent import AgentObservation
from sh15.agents.action_executor import ActionExecutor


# ===== 工具函数 =====

def grpc_course_to_agent_heading(course_deg: float) -> float:
    """
    将gRPC接口的航向 (度, 0=正北, 顺时针) 转换为智能体使用的航向 (弧度, 0=正东, 逆时针).
    """
    math_deg = (90 - course_deg) % 360
    return math.radians(math_deg)


def agent_heading_to_grpc_course(heading_rad: float) -> float:
    """
    将智能体使用的航向 (弧度, 0=正东, 逆时针) 转换为gRPC接口的航向 (度, 0=正北, 顺时针).
    """
    math_deg = math.degrees(heading_rad)
    grpc_deg = (90 - math_deg) % 360
    return grpc_deg


def parse_unit_name(name: str) -> Tuple[str, int]:
    """
    解析单位名称，返回类型和ID
    例如: "white_usv1" -> ("white_usv", 1)
    """
    import re
    match = re.match(r'([a-z_]+)(\d+)', name)
    if match:
        return match.group(1), int(match.group(2))
    return "", -1


# ===== 数据转换函数 =====

def convert_white_boat_to_grpc(boat: WhiteBoat, current_time: float) -> dict:
    """将白方无人艇对象转换为gRPC接口格式"""
    # 计算速度向量
    vx = boat.speed * math.cos(boat.heading)
    vy = boat.speed * math.sin(boat.heading)
    
    # 获取停靠的无人机名称列表
    uav_list = []
    # 这里需要从无人机列表中查找，暂时留空，在实际调用时填充
    
    # 获取锁定相关信息
    locked_attacker = ""
    relative_orientation = 0.0
    locking_unit = ""
    
    if hasattr(boat, 'current_target') and boat.current_target:
        locking_unit = f"black_usv{boat.current_target.id + 1}"
    
    return {
        "name": f"white_usv{boat.id + 1}",
        "is_alive": boat.active,
        "position": [boat.x, boat.y],
        "velocity": [vx, vy],
        "course": agent_heading_to_grpc_course(boat.heading),
        "speed": boat.speed,
        "is_locked": False,  # 需要从环境中计算
        "is_locking": boat.is_locking,
        "is_frozen": boat.is_frozen(current_time),
        "locked_times": boat.locked_times,
        "locked_attacker": locked_attacker,
        "relative_orientation": relative_orientation,
        "locking_unit": locking_unit,
        "uav": uav_list
    }


def convert_white_drone_to_grpc(drone: WhiteDrone, current_time: float) -> dict:
    """将白方无人机对象转换为gRPC接口格式"""
    # 计算速度向量
    vx = drone.speed * math.cos(drone.heading)
    vy = drone.speed * math.sin(drone.heading)
    
    # 计算剩余飞行时间（秒）
    # 假设满电飞行时间为 GameConfig.WHITE_DRONE_FLIGHT_TIME
    battery_seconds = (drone.energy / 100.0) * GameConfig.WHITE_DRONE_FLIGHT_TIME
    
    # 确定home_name
    home_name = f"white_usv{drone.parent_boat_id + 1}" if drone.parent_boat_id is not None else ""
    
    return {
        "name": f"white_uav{drone.id + 1}",
        "is_alive": drone.active,
        "position": [drone.x, drone.y],
        "velocity": [vx, vy],
        "course": agent_heading_to_grpc_course(drone.heading),
        "speed": drone.speed,
        "battery": battery_seconds,
        "is_charging": drone.state == "recharging",
        "is_at_usv": drone.state in ["recharging", "ready"],
        "home_name": home_name
    }


def convert_black_boat_to_grpc_full(boat: BlackBoat) -> dict:
    """将黑方无人艇转换为完整信息格式（用于 black_usv_states）"""
    return {
        "name": f"black_usv{boat.id + 1}",
        "is_alive": boat.active,
        "is_frozen": boat.is_frozen(0.0),  # 当前时间在调用处传入
        "locked_times": boat.locked_times
    }


def convert_black_boat_to_observation(boat: BlackBoat) -> dict:
    """将黑方无人艇转换为观测信息格式（用于 white_observation）"""
    # 计算速度向量
    if hasattr(boat, 'velocity') and boat.velocity:
        vx, vy = boat.velocity[0], boat.velocity[1]
    else:
        vx = boat.speed * math.cos(boat.heading)
        vy = boat.speed * math.sin(boat.heading)
    
    return {
        "name": f"black_usv{boat.id + 1}",
        "position": [boat.x, boat.y],
        "velocity": [vx, vy]
    }


def generate_white_observation(white_boats: List[WhiteBoat], 
                               white_drones: List[WhiteDrone], 
                               black_boats: List[BlackBoat]) -> List[dict]:
    """
    模拟白方探测系统，生成可见的黑方单位列表
    """
    visible_black_boats = []
    
    for black_boat in black_boats:
        if not black_boat.active:
            continue
            
        is_detected = False
        
        # 检查是否在任何白方无人艇的探测范围内
        for white_boat in white_boats:
            if not white_boat.active:
                continue
            distance = white_boat.distance_to(black_boat)
            if distance <= GameConfig.WHITE_BOAT_DETECT_RANGE:
                is_detected = True
                break
        
        # 检查是否在任何白方无人机的探测范围内（扇形探测）
        if not is_detected:
            for drone in white_drones:
                if not drone.active or drone.state not in ["flying", "returning"]:
                    continue
                    
                distance = drone.distance_to(black_boat)
                if distance <= GameConfig.WHITE_DRONE_DETECT_RANGE:
                    # 简化：这里不实现扇形检测，直接使用圆形
                    # 完整实现需要检查角度是否在扇形范围内
                    is_detected = True
                    break
        
        if is_detected:
            visible_black_boats.append(convert_black_boat_to_observation(black_boat))
    
    return visible_black_boats


# ===== 简化的黑方智能体 =====

class SimpleDefensiveBlackAgent:
    """
    简化的黑方智能体
    - 支持从测试用例加载路径
    - 执行防御性锁定
    """
    
    def __init__(self, test_case_config: Optional[Dict] = None):
        self.config = test_case_config
        self.boat_paths = {}
        self.boat_current_target = {}
        
    def reset(self):
        """重置智能体状态"""
        self.boat_paths = {}
        self.boat_current_target = {}
        
    def initialize_paths(self, black_boats: List[BlackBoat]):
        """初始化黑方无人艇的路径"""
        if not self.config or 'black_boat_paths' not in self.config:
            return
            
        for i, boat in enumerate(black_boats):
            usv_key = f"usv{i+1}"
            if usv_key in self.config['black_boat_paths']:
                self.boat_paths[boat.id] = self.config['black_boat_paths'][usv_key]
                self.boat_current_target[boat.id] = 0
                
                # 设置初始位置为第一个路径点
                if self.boat_paths[boat.id]:
                    first_point = self.boat_paths[boat.id][0]["point"]
                    boat.x = first_point[0]
                    boat.y = first_point[1]
                    boat.speed = self.boat_paths[boat.id][0]["speed"]
    
    def update_all_black_boats(self, core_env: CoreEnvironment, dt: float):
        """更新所有黑方无人艇"""
        current_time = core_env.current_time
        
        for boat in core_env.black_boats:
            if not boat.active or boat.is_frozen(current_time):
                continue
            
            # 如果有路径，按路径移动
            if boat.id in self.boat_paths:
                self._update_boat_path(boat, dt)
            
            # 执行防御性锁定
            self._attempt_defensive_lock(boat, core_env.white_boats, current_time)
    
    def _update_boat_path(self, boat: BlackBoat, dt: float):
        """更新单艘船的路径跟踪"""
        if boat.id not in self.boat_paths:
            return
            
        path = self.boat_paths[boat.id]
        current_target_idx = self.boat_current_target[boat.id]
        
        if current_target_idx >= len(path):
            return
            
        target_point = path[current_target_idx]
        target_x, target_y = target_point["point"]
        target_speed = target_point["speed"]
        
        # 计算到目标点的距离
        dx = target_x - boat.x
        dy = target_y - boat.y
        distance = math.sqrt(dx**2 + dy**2)
        
        # 如果接近目标点，切换到下一个目标点
        if distance < target_speed * dt * 2:
            self.boat_current_target[boat.id] += 1
            if self.boat_current_target[boat.id] < len(path):
                next_target = path[self.boat_current_target[boat.id]]
                target_x, target_y = next_target["point"]
                target_speed = next_target["speed"]
                dx = target_x - boat.x
                dy = target_y - boat.y
                distance = math.sqrt(dx**2 + dy**2)
        
        # 移动向目标点
        if distance > 0:
            direction_x = dx / distance
            direction_y = dy / distance
            
            target_heading = math.atan2(direction_y, direction_x)
            boat.move_with_kinematics(target_speed, target_heading, dt)
    
    def _attempt_defensive_lock(self, boat: BlackBoat, white_boats: List[WhiteBoat], current_time: float):
        """尝试防御性锁定进入范围的白方"""
        # 寻找最近的白方目标
        nearest_white = None
        min_distance = float('inf')
        
        for white_boat in white_boats:
            if not white_boat.active:
                continue
                
            distance = boat.distance_to(white_boat)
            
            if distance <= GameConfig.BLACK_BOAT_LOCK_RANGE and distance < min_distance:
                min_distance = distance
                nearest_white = white_boat
        
        # 如果找到目标，尝试锁定
        if nearest_white:
            LockingSystem.try_black_boat_lock(boat, nearest_white.id, current_time)


# ===== Mock 仿真服务器 =====

class MockSimulationServer:
    """Mock gRPC 仿真服务器"""
    
    def __init__(self, test_case_path: Optional[str] = None, port: int = 6000):
        """
        初始化Mock服务器
        
        Args:
            test_case_path: 测试用例JSON文件路径（可选）
            port: gRPC服务端口
        """
        print("=" * 60)
        print("Mock gRPC 仿真服务器初始化中...")
        print("=" * 60)
        
        self.port = port
        self.core_env = CoreEnvironment()
        self.action_executor = ActionExecutor()
        self.drone_manager = DroneManager()
        
        # 加载测试用例（如果提供）
        self.test_case_config = None
        if test_case_path and os.path.exists(test_case_path):
            print(f"加载测试用例: {test_case_path}")
            with open(test_case_path, 'r', encoding='utf-8') as f:
                test_case_data = json.load(f)
                self.test_case_config = {
                    'black_boat_count': test_case_data.get('usvNum', 5),
                    'black_boat_paths': {k: v for k, v in test_case_data.items() 
                                        if k.startswith('usv') and k != 'usvNum'}
                }
        
        # 创建黑方智能体
        self.black_agent = SimpleDefensiveBlackAgent(self.test_case_config)
        
        # 命令缓存
        self.pending_commands = {
            'movements': {},  # {unit_name: (speed, heading)}
            'locks': [],      # [(unit1_name, unit2_name)]
            'takeoffs': [],   # [(uav_name, home_name, speed, heading)]
            'landings': []    # [(uav_name, usv_name)]
        }
        
        # 单位名称映射
        self.white_boat_map: Dict[str, WhiteBoat] = {}
        self.white_drone_map: Dict[str, WhiteDrone] = {}
        self.black_boat_map: Dict[str, BlackBoat] = {}
        
        # 仿真参数
        self.simulation_ratio = 1.0  # 仿真倍率
        self.auto_step = True  # 是否在get_state时自动推进
        
        # 初始化环境
        self._initialize_environment()
        
        print("初始化完成！")
        print(f"- 白方无人艇: {len(self.core_env.white_boats)}")
        print(f"- 白方无人机: {len(self.core_env.all_white_drones)}")
        print(f"- 黑方无人艇: {len(self.core_env.black_boats)}")
        print("=" * 60)
    
    def _initialize_environment(self):
        """初始化环境"""
        # 重置核心环境
        self.core_env.reset()
        
        # 如果有测试用例，覆盖黑方初始化
        if self.test_case_config:
            # 设置黑方数量
            black_count = self.test_case_config['black_boat_count']
            if black_count != len(self.core_env.black_boats):
                # 重新初始化黑方（简化处理，直接修改数量）
                pass
            
            # 初始化黑方路径
            self.black_agent.initialize_paths(self.core_env.black_boats)
        
        # 重置黑方智能体
        self.black_agent.reset()
        if self.test_case_config:
            self.black_agent.initialize_paths(self.core_env.black_boats)
        
        # 构建名称映射
        self._rebuild_unit_maps()
    
    def _rebuild_unit_maps(self):
        """重建单位名称映射"""
        self.white_boat_map.clear()
        self.white_drone_map.clear()
        self.black_boat_map.clear()
        
        for boat in self.core_env.white_boats:
            name = f"white_usv{boat.id + 1}"
            self.white_boat_map[name] = boat
        
        for drone in self.core_env.all_white_drones:
            name = f"white_uav{drone.id + 1}"
            self.white_drone_map[name] = drone
        
        for boat in self.core_env.black_boats:
            name = f"black_usv{boat.id + 1}"
            self.black_boat_map[name] = boat
    
    def _step_simulation(self):
        """推进仿真一步"""
        dt = GameConfig.TIME_STEP
        current_time = self.core_env.current_time
        
        # 1. 应用缓存的移动指令
        for unit_name, (speed, heading) in self.pending_commands['movements'].items():
            # 查找单位
            unit = None
            if unit_name in self.white_boat_map:
                unit = self.white_boat_map[unit_name]
            elif unit_name in self.white_drone_map:
                unit = self.white_drone_map[unit_name]
            
            if unit and unit.active and not unit.is_frozen(current_time):
                unit.move_with_kinematics(speed, heading, dt)
        
        # 2. 应用锁定指令
        for unit1_name, unit2_name in self.pending_commands['locks']:
            if unit1_name in self.white_boat_map and unit2_name in self.black_boat_map:
                white_boat = self.white_boat_map[unit1_name]
                black_boat = self.black_boat_map[unit2_name]
                if white_boat.active and black_boat.active:
                    LockingSystem.try_white_boat_lock(white_boat, black_boat.id, current_time)
        
        # 3. 应用起飞指令
        for uav_name, home_name, speed, heading in self.pending_commands['takeoffs']:
            if uav_name in self.white_drone_map:
                drone = self.white_drone_map[uav_name]
                if drone.state in ["recharging", "ready"] and drone.docked_on_boat_id is not None:
                    # 简化起飞逻辑
                    drone.state = "flying"
                    drone.docked_on_boat_id = None
                    drone.speed = speed
                    drone.heading = heading
        
        # 4. 应用降落指令
        for uav_name, usv_name in self.pending_commands['landings']:
            if uav_name in self.white_drone_map and usv_name in self.white_boat_map:
                drone = self.white_drone_map[uav_name]
                boat = self.white_boat_map[usv_name]
                
                # 检查降落条件
                distance = drone.distance_to(boat)
                if (distance <= GameConfig.WHITE_DRONE_LANDING_DISTANCE and 
                    drone.speed <= GameConfig.WHITE_DRONE_LANDING_SPEED):
                    # 简化降落逻辑
                    drone.state = "recharging"
                    drone.docked_on_boat_id = boat.id
                    drone.x = boat.x
                    drone.y = boat.y
                    drone.speed = 0
        
        # 清空命令缓存
        self.pending_commands['movements'].clear()
        self.pending_commands['locks'].clear()
        self.pending_commands['takeoffs'].clear()
        self.pending_commands['landings'].clear()
        
        # 5. 更新黑方行为
        self.black_agent.update_all_black_boats(self.core_env, dt)
        
        # 6. 更新无人机能量
        for drone in self.core_env.all_white_drones:
            if drone.state == "flying":
                # 消耗能量
                energy_consumption_rate = 100.0 / GameConfig.WHITE_DRONE_FLIGHT_TIME  # %/秒
                drone.energy = max(0, drone.energy - energy_consumption_rate * dt)
                
                # 能量耗尽自动降落
                if drone.energy <= 0:
                    drone.state = "returning"
            elif drone.state == "recharging":
                # 充电
                energy_recharge_rate = 100.0 / GameConfig.WHITE_DRONE_RECHARGE_TIME  # %/秒
                drone.energy = min(100.0, drone.energy + energy_recharge_rate * dt)
                
                # 充满电切换到就绪状态
                if drone.energy >= 100.0:
                    drone.state = "ready"
        
        # 7. 更新环境系统
        # 碰撞检测
        from sh15.core.CollisionSystem import CollisionSystem
        CollisionSystem.check_all_collisions(self.core_env.white_boats, self.core_env.black_boats)
        
        # 边界检查
        from sh15.core.BoundarySystem import BoundarySystem
        for black_boat in self.core_env.black_boats:
            BoundarySystem.check_breakthrough(black_boat)
        
        # 更新时间
        self.core_env.current_time += dt
    
    # ===== gRPC 接口处理方法 =====
    
    def handle_get_state(self) -> dict:
        """处理 get_state 请求"""
        # 自动推进仿真
        if self.auto_step:
            self._step_simulation()
        
        current_time = self.core_env.current_time
        
        # 转换白方无人艇状态
        white_usv_states = []
        for boat in self.core_env.white_boats:
            boat_data = convert_white_boat_to_grpc(boat, current_time)
            
            # 填充停靠的无人机列表
            uav_list = []
            for drone in self.core_env.all_white_drones:
                if (drone.docked_on_boat_id == boat.id and 
                    drone.state in ["recharging", "ready"]):
                    uav_list.append(f"white_uav{drone.id + 1}")
            boat_data["uav"] = uav_list
            
            white_usv_states.append(boat_data)
        
        # 转换白方无人机状态
        white_uav_states = []
        for drone in self.core_env.all_white_drones:
            drone_data = convert_white_drone_to_grpc(drone, current_time)
            white_uav_states.append(drone_data)
        
        # 转换黑方无人艇完整状态
        black_usv_states = []
        for boat in self.core_env.black_boats:
            boat_data = convert_black_boat_to_grpc_full(boat)
            black_usv_states.append(boat_data)
        
        # 生成白方观测
        white_observation = generate_white_observation(
            self.core_env.white_boats,
            self.core_env.all_white_drones,
            self.core_env.black_boats
        )
        
        # 构造返回数据
        state_data = {
            "time": current_time,
            "ratio": self.simulation_ratio,
            "num_white_usv": len([b for b in self.core_env.white_boats if b.active]),
            "num_black_usv": len([b for b in self.core_env.black_boats if b.active]),
            "white_usv_states": white_usv_states,
            "white_uav_states": white_uav_states,
            "black_usv_states": black_usv_states,
            "white_observation": white_observation
        }
        
        return state_data
    
    def handle_send_command(self, unit_name: str, target_speed: float, target_course: float) -> str:
        """处理 send_command 请求"""
        # 转换航向
        target_heading = grpc_course_to_agent_heading(target_course)
        
        # 缓存命令
        self.pending_commands['movements'][unit_name] = (target_speed, target_heading)
        
        return f"Command accepted for {unit_name}"
    
    def handle_cmd_lock(self, unit1_name: str, unit2_name: str) -> bool:
        """处理 cmd_lock 请求"""
        # 验证单位存在
        if unit1_name not in self.white_boat_map or unit2_name not in self.black_boat_map:
            return False
        
        # 缓存锁定命令
        self.pending_commands['locks'].append((unit1_name, unit2_name))
        
        return True
    
    def handle_cmd_uav_takeoff(self, unit_name: str, home_name: str, 
                               target_speed: float, target_course: float) -> bool:
        """处理 cmd_uav_takeoff 请求"""
        # 验证单位存在
        if unit_name not in self.white_drone_map or home_name not in self.white_boat_map:
            return False
        
        drone = self.white_drone_map[unit_name]
        
        # 检查是否可以起飞
        if drone.state not in ["recharging", "ready"]:
            return False
        
        # 转换航向
        target_heading = grpc_course_to_agent_heading(target_course)
        
        # 缓存起飞命令
        self.pending_commands['takeoffs'].append((unit_name, home_name, target_speed, target_heading))
        
        return True
    
    def handle_cmd_uav_land(self, uav_name: str, usv_name: str) -> bool:
        """处理 cmd_uav_land 请求"""
        # 验证单位存在
        if uav_name not in self.white_drone_map or usv_name not in self.white_boat_map:
            return False
        
        # 缓存降落命令
        self.pending_commands['landings'].append((uav_name, usv_name))
        
        return True
    
    # ===== gRPC 服务实现 =====
    
    def serve(self):
        """启动gRPC服务器"""
        server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
        
        # 创建服务实例
        servicer = MockSimulationServicer(self)
        simserver_pb2_grpc.add_GreeterServicer_to_server(servicer, server)
        
        # 绑定端口
        server.add_insecure_port(f'[::]:{self.port}')
        
        print(f"\n{'=' * 60}")
        print(f"Mock gRPC 服务器已启动")
        print(f"监听端口: {self.port}")
        print(f"{'=' * 60}\n")
        
        server.start()
        
        try:
            server.wait_for_termination()
        except KeyboardInterrupt:
            print("\n\n正在关闭服务器...")
            server.stop(0)
            print("服务器已关闭。")


class MockSimulationServicer(simserver_pb2_grpc.GreeterServicer):
    """gRPC 服务实现"""
    
    def __init__(self, mock_server: MockSimulationServer):
        self.mock_server = mock_server
    
    def control(self, request, context):
        """处理控制请求"""
        try:
            # 解析请求
            msg_data = json.loads(request.msg)
            func_name = msg_data.get("func_name", "")
            kwargs = msg_data.get("kwargs", {})
            
            # 路由到对应的处理方法
            if func_name == "get_state":
                result_data = self.mock_server.handle_get_state()
                return simserver_pb2.MsgStr(
                    msg="State retrieved successfully",
                    data=json.dumps(result_data)
                )
            
            elif func_name == "send_command":
                result_msg = self.mock_server.handle_send_command(
                    unit_name=kwargs.get("unit_name", ""),
                    target_speed=kwargs.get("target_speed", 0.0),
                    target_course=kwargs.get("target_course", 0.0)
                )
                return simserver_pb2.MsgStr(msg=result_msg)
            
            elif func_name == "cmd_lock":
                result = self.mock_server.handle_cmd_lock(
                    unit1_name=kwargs.get("unit1_name", ""),
                    unit2_name=kwargs.get("unit2_name", "")
                )
                return simserver_pb2.MsgStr(
                    msg=f"Lock command result: {result}",
                    data=json.dumps({"success": result})
                )
            
            elif func_name == "cmd_uav_takeoff":
                result = self.mock_server.handle_cmd_uav_takeoff(
                    unit_name=kwargs.get("unit_name", ""),
                    home_name=kwargs.get("home_name", ""),
                    target_speed=kwargs.get("target_speed", 20.0),
                    target_course=kwargs.get("target_course", 0.0)
                )
                return simserver_pb2.MsgStr(
                    msg=f"Takeoff command result: {result}",
                    data=json.dumps({"success": result})
                )
            
            elif func_name == "cmd_uav_land":
                result = self.mock_server.handle_cmd_uav_land(
                    uav_name=kwargs.get("uav_name", ""),
                    usv_name=kwargs.get("usv_name", "")
                )
                return simserver_pb2.MsgStr(
                    msg=f"Land command result: {result}",
                    data=json.dumps({"success": result})
                )
            
            else:
                return simserver_pb2.MsgStr(
                    msg=f"Unknown function: {func_name}"
                )
        
        except Exception as e:
            import traceback
            error_msg = f"Error processing request: {e}\n{traceback.format_exc()}"
            print(error_msg)
            return simserver_pb2.MsgStr(msg=error_msg)


# ===== 主程序 =====

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Mock gRPC 仿真服务器')
    parser.add_argument('--test_case', type=str, default=None,
                       help='测试用例JSON文件路径（可选）')
    parser.add_argument('--port', type=int, default=6000,
                       help='gRPC服务端口（默认6000）')
    
    args = parser.parse_args()
    
    # 创建并启动服务器
    server = MockSimulationServer(
        test_case_path=args.test_case,
        port=args.port
    )
    
    server.serve()

